package world.placement;

/**
 * A class representing a certain position in a coordinate system.
 * 
 * @author Frederic Mes, Wim Marynissen
 * @version 1.0
 */
public class Position {
	
	/**
	 * @param 	xCoord
	 * 			The x-direction coordinate value.
	 * @param 	yCoord
	 * 			The y-direction coordinate value.
	 * @param 	zCoord
	 * 			The z-direction coordinate value.	
	 * @post	The new x coordinate is equal to the one specified.
	 * 			| new.getXCoord() == xCoord
	 * @post	The new y coordinate is equal to the one specified.
	 * 			| new.getYCoord() == yCoord
	 * @post	The new z coordinate is equal to the one specified.
	 * 			| new.getZCoord() == zCoord	
	 */
	public Position (long xCoord, long yCoord, long zCoord){
		setCoords (xCoord, yCoord, zCoord);	
	}
	
	/**
	 * Returns the coordinate in the x-direction.	
	 */
	public long getXCoord() {
		return xCoord;
	}
	/**
	 * @param 	xCoord
	 * 			The new x-direction coordinate.
	 * @post	The new x coordinate is equal to the one specified.
	 * 			| new.getXCoord() == xCoord
	 */
	public void setXCoord(long xCoord) {
		this.xCoord = xCoord;
	}
	/**
	 * Returns the coordinate in the y-direction.	
	 */
	public long getYCoord() {
		return yCoord;
	}
	/**
	 * @param 	yCoord
	 * 			The new y-direction coordinate.
	 * @post	The new y coordinate is equal to the one specified.
	 * 			| new.getYCoord() == yCoord
	 */
	public void setYCoord(long yCoord) {
		this.yCoord = yCoord;
	}
	/**
	 * Returns the coordinate in the z-direction.	
	 */
	public long getZCoord() {
		return zCoord;
	}
	/**
	 * @param 	zCoord
	 * 			The new z-direction coordinate.
	 * @post	The new z coordinate is equal to the one specified.
	 * 			| new.getZCoord() == zCoord
	 */
	public void setZCoord(long zCoord) {
		this.zCoord = zCoord;
	}
	
	/**
	 * @param 	xCoord
	 * 			The new x-direction coordinate.
	 * @param 	yCoord
	 * 			The new y-direction coordinate.
	 * @param 	zCoord
	 * 			The new z-direction coordinate.
	 * @post	The new x coordinate is equal to the one specified.
	 * 			| new.getXCoord() == xCoord
	 * @post	The new y coordinate is equal to the one specified.
	 * 			| new.getYCoord() == yCoord
	 * @post	The new z coordinate is equal to the one specified.
	 * 			| new.getZCoord() == zCoord
	 */
	public void setCoords (long xCoord, long yCoord, long zCoord){
		setXCoord (xCoord);
		setYCoord (yCoord);
		setZCoord (zCoord);
	}
	/**
	 * Variable holding x coordinate value.
	 */
	private long xCoord;
	/**
	 * Variable holding y coordinate value.
	 */
	private long yCoord;
	/**
	 * Variable holding z coordinate value.
	 */
	private long zCoord;
	
	/**
	 * Check whether this postion is equal to the specified object.
	 *
	 * @return  False if the object is non-effective or an object from a different class.
	 *        	| if((object == null)
	 *        	|   	|| (object.getClass() != Position.class))
	 *        	|   then result == false
	 * @return  True if the other object is a postion and has the same coordinates as this position,
	 *        	| if (object instanceof Position)
	 *        	| 	then result == (otherPosition.getXCoord() == getXCoord()) 
	 *        	|					&& (otherPosition.getYCoord() == getYCoord())
	 *        	|					&& (otherPosition.getZCoord() == getZCoord())
	 */
	@Override
	 public boolean equals(Object object) {
         if((object == null) || (object.getClass() != Position.class))
                 return false;
         Position otherPosition = (Position) object;
         return (otherPosition.getXCoord() == getXCoord()) 
         			&& (otherPosition.getYCoord() == getYCoord())
         			&& (otherPosition.getZCoord() == getZCoord());
 }

	
	
	/**
	 * @param 	direction
	 * 			The direction of the neighbour square, relative to the one at this position.
	 * @return	The position of neighbour square.
	 * @throws 	IllegalArgumentException
	 * 			The specified direction is non-effective
	 * 			| (direction == null)
	 */
	public Position getPositionInDirection (Direction direction) throws IllegalArgumentException{
		if(direction == null)
			throw new IllegalArgumentException("Non-effective direction specified.");
		switch(direction){
			case NORTH : return new Position (getXCoord(), getYCoord() + 1, getZCoord());
			case SOUTH : return new Position (getXCoord(), getYCoord() - 1, getZCoord());
			case EAST : return new Position (getXCoord() + 1, getYCoord(), getZCoord());
			case WEST : return new Position (getXCoord() - 1, getYCoord(), getZCoord());
			case CEILING : return new Position (getXCoord(), getYCoord(), getZCoord() + 1);
			case FLOOR : return new Position (getXCoord(), getYCoord(), getZCoord() - 1);
		}
		return null;
	
	}
	
	@Override
    public String toString() {
            return "(" + getXCoord() + "," + getYCoord() + "," + getZCoord() + ")";
    }
}
